﻿using MesGLApp.DAL.MesDB;
using MesGLApp.DAL.MesDTO;
using MesGLApp.DAL.RoleDB;
using MesGLApp.DAL.RoleDTO;
using MesGLApp.Tools;
using MesGLApp.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Threading.Tasks;

namespace MesGLApp.BLL.Mes
{
    public class ProdProcScanControler : BaseControler
    {

        /// <summary>
        /// 查询所有父站点，并将子站点一并查询出来
        /// </summary>
        /// <returns></returns>
        public List<SiteInfoDTO> SearchParentSite()
        {
            List<SiteInfoDTO> resList = new List<SiteInfoDTO>();
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.SiteInfos;
                if (query != null && query.Count() > 0)
                {
                    var parQuery = query.ToList().Where(p => p.ParentID == 0);
                    if (parQuery != null && parQuery.Count() > 0)
                    {
                        foreach (var parItem in parQuery)
                        {
                            SiteInfoDTO par = new SiteInfoDTO();
                            EntityTools.CopyEntity(parItem, ref par);

                            var childQuery = query.Where(c => c.ParentID == parItem.ID);
                            if (childQuery != null && childQuery.Count() > 0)
                            {
                                par.ChildSiteList = new List<SiteInfo>();
                                foreach (var childItem in childQuery)
                                {
                                    SiteInfo child = new SiteInfo();
                                    EntityTools.CopyEntity(childItem, ref child);
                                    par.ChildSiteList.Add(child);
                                }
                            }

                            resList.Add(par);
                        }
                    }
                }
                if (query != null && query.Count() > 0)
                {
                    

                    
                }
            }
            return resList;
        }


        /// <summary>
        /// 查询同一类型的状态
        /// </summary>
        /// <returns></returns>
        public List<StatusInfo> SearchStatusInfoByTypeName(string typeName)
        {
            List<StatusInfo> resList = new List<StatusInfo>();
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.StatusTypes
                            join b in ctx.StatusInfos on a.ID equals b.StypeID into res
                            from ab in res.DefaultIfEmpty()
                            where a.StypeName == typeName
                            select ab;
                if (query != null && query.Count() > 0)
                {
                    foreach (var item in query)
                    {
                        if (item != null && item.ID > 0)
                        {
                            resList.Add(item);
                        }
                    }
                }
            }
            return resList;
        }


        public List<TargetProdProcessDTO> SearchTargetForPause(string prodNo, SiteInfo site, Boolean isFause)
        {
            List<TargetProdProcessDTO> resList = new List<TargetProdProcessDTO>();
            using (MesDB ctx = new MesDB())
            {
                List<int> siteList = new List<int>();
                var siteQuery = ctx.SiteInfos.Where(s => s.ParentID == site.ID);
                if (siteQuery != null && siteQuery.Count() > 0)
                {
                    foreach (var item in siteQuery)
                    {
                        siteList.Add(item.ID);
                    }
                }

                StatusInfo status = new StatusInfo();
                var statusQuery = ctx.StatusInfos.Where(s => s.StatusValue.Equals("暂停"));
                if (statusQuery != null && statusQuery.Count() > 0)
                {
                    status = statusQuery.First();
                }

                var query = from a in ctx.TargetProdProcesses
                            join b in ctx.ProdProcSites on a.ID equals b.ProdProcID into res1
                            from ab in res1.DefaultIfEmpty()
                            join c in ctx.SiteGroups on ab.SiteGroupID equals c.ID into res2
                            from bc in res2.DefaultIfEmpty()
                            where siteList.Contains(a.CurrSiteID)
                            select new { A = a, AB = ab, BC = bc };
                if (query != null && query.Count() > 0)
                {
                    foreach (var item in query) 
                    {
                        TargetProdProcessDTO resTarget = new TargetProdProcessDTO();
                        EntityTools.CopyEntity<TargetProdProcess, TargetProdProcessDTO>(item.A, ref resTarget);
                        SiteGroupDTO siteGroup = new SiteGroupDTO();
                        EntityTools.CopyEntity<SiteGroup, SiteGroupDTO>(item.BC, ref siteGroup);
                        resTarget.SiteGroup = siteGroup;
                        resList.Add(resTarget);
                    }
                }

                if (prodNo != null && prodNo.Trim().Length > 0)
                {
                    resList = resList.Where(t => t.ProdNumber.Contains(prodNo)).ToList();
                }
                if (isFause)
                {
                    resList = resList.Where(t => t.ErrStatusID == status.ID).ToList();
                }
                else
                {
                    resList = resList.Where(t => t.ErrStatusID != status.ID).ToList();
                }
            }

            return resList;
        }


        /// <summary>
        /// 通过二维码查询工单信息
        /// </summary>
        /// <param name="prodNo">工单号</param>
        /// <returns></returns>
        public TargetProdProcessDTO SearchTargetForScan(string prodNo)
        {
            TargetProdProcessDTO resTarget = null;
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.TargetProdProcesses
                            join b in ctx.ProdProcSites on a.ID equals b.ProdProcID into res1
                            from ab in res1.DefaultIfEmpty()
                            join c in ctx.SiteGroups on ab.SiteGroupID equals c.ID into res2
                            from bc in res2.DefaultIfEmpty()
                            join d in ctx.TargetPPCycle on a.ID equals d.TargetID into res3
                            from ad in res3.DefaultIfEmpty()
                            where a.ProdNumber == prodNo
                            select new {A = a,AB = ab,BC = bc,AD = ad};
                if (query != null && query.Count() > 0)
                {
                    resTarget = new TargetProdProcessDTO();
                    EntityTools.CopyEntity<TargetProdProcess, TargetProdProcessDTO>(query.First().A,ref resTarget);
                    if (query.First().AD != null)
                    {
                        resTarget.TargetCycle = query.First().AD;
                    }

                    if (query.First().BC != null)
                    {
                        SiteGroupDTO siteGroup = new SiteGroupDTO();
                        EntityTools.CopyEntity<SiteGroup, SiteGroupDTO>(query.First().BC,ref siteGroup);
                        resTarget.SiteGroup = siteGroup;

                        var siteQuery = from a in ctx.SiteGroups
                                        join b in ctx.SiteInfoGroups on a.ID equals b.GroupID into res1
                                        from ab in res1.DefaultIfEmpty()
                                        join c in ctx.SiteInfos on ab.SiteID equals c.ID into res2
                                        from bc in res2.DefaultIfEmpty()
                                        where a.ID == resTarget.SiteGroup.ID
                                        orderby ab.Sort 
                                        select new {A = a,AB = ab, BC = bc};
                        if (siteQuery != null && siteQuery.Count() > 0)
                        {
                            resTarget.SiteGroup.SiteInfoList = new List<SiteInfoGroupDTO>();
                            foreach (var item in siteQuery)
                            {
                                if (item.AB != null && item.BC != null)
                                {
                                    SiteInfoGroupDTO groupBean = new SiteInfoGroupDTO();
                                    SiteInfo siteBean = new SiteInfo();
                                    EntityTools.CopyEntity(item.BC,ref siteBean);
                                    EntityTools.CopyEntity(item.AB, ref groupBean);
                                    groupBean.SiteInfo = siteBean;
                                    resTarget.SiteGroup.SiteInfoList.Add(groupBean);
                                }
                            }
                        }

                        var scanQuery = ctx.ProdProcScans.Where(q => q.ProdProcID == resTarget.ID);
                        resTarget.scanList = scanQuery != null && scanQuery.Count() > 0 ? scanQuery.ToList<ProdProcScan>() : null;
                    }
                }
            }
            return resTarget;
        }


        /// <summary>
        /// 查询所有工单
        /// </summary>
        /// <returns></returns>
        public List<TargetProdProcessDTO> SearchAllProdProcess()
        {
            List<TargetProdProcessDTO> resList = new List<TargetProdProcessDTO>();
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.TargetProdProcesses
                            join b in ctx.ProdProcSites on a.ID equals b.ProdProcID into res1
                            from ab in res1
                            join c in ctx.SiteGroups on ab.SiteGroupID equals c.ID into res2
                            from bc in res2
                            select new { A = a, BC = bc };
                if (query != null && query.Count() > 0)
                {
                    List<string> prodList = new List<string>();
                    foreach (var item in query)
                    {
                        TargetProdProcessDTO tmpTarget = new TargetProdProcessDTO();
                        EntityTools.CopyEntity<TargetProdProcess, TargetProdProcessDTO>(item.A, ref tmpTarget);

                        SiteGroupDTO siteGroup = new SiteGroupDTO();
                        EntityTools.CopyEntity<SiteGroup, SiteGroupDTO>(item.BC, ref siteGroup);
                        tmpTarget.SiteGroup = siteGroup;
                        resList.Add(tmpTarget);

                        string tmpProd = tmpTarget.ProdNumber.Split('-')[0];
                        if (prodList.Contains(tmpProd) == false)
                        {
                            prodList.Add(tmpProd);
                        }
                    }

                    var sourceQuery = ctx.SourcePPCycle.Where(s => prodList.Contains(s.ProdNumber));
                    if (sourceQuery != null && sourceQuery.Count() > 0)
                    {
                        List<SourcePPCycle> cycleList = sourceQuery.ToList();
                        foreach (var item in resList)
                        {
                            var tmpQuery = cycleList.Where(c => c.ProdNumber.Equals(item.ProdNumber.Split('-')[0]));
                            if (tmpQuery != null && tmpQuery.Count() > 0)
                            {
                                item.SourceCycle = tmpQuery.First();
                            }
                        }
                    }
                }
            }
            return resList;
        }

        /// <summary>
        /// 查询未做完的工单
        /// </summary>
        /// <returns></returns>
        public List<TargetProdProcessDTO> SearchTargetForNoComplete()
        {
            List<TargetProdProcessDTO> resList = new List<TargetProdProcessDTO>();
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.TargetProdProcesses
                            join b in ctx.ProdProcSites on a.ID equals b.ProdProcID into res1
                            from ab in res1
                            join c in ctx.SiteGroups on ab.SiteGroupID equals c.ID into res2
                            from bc in res2
                            join d in ctx.StatusInfos on a.ProdStatusID equals d.ID into res3
                            from ad in res3
                            where !ad.StatusValue.Equals("上线") && !ad.StatusValue.Equals("已完成")
                            select new { A = a, AB = ab, BC = bc };
                if (query != null && query.Count() > 0)
                {
                    foreach (var item in query)
                    {
                        TargetProdProcessDTO tmpTarget = new TargetProdProcessDTO();
                        EntityTools.CopyEntity<TargetProdProcess, TargetProdProcessDTO>(item.A, ref tmpTarget);

                        SiteGroupDTO siteGroup = new SiteGroupDTO();
                        EntityTools.CopyEntity<SiteGroup, SiteGroupDTO>(item.BC, ref siteGroup);
                        tmpTarget.SiteGroup = siteGroup;

                        var siteQuery = from a in ctx.SiteGroups
                                        join b in ctx.SiteInfoGroups on a.ID equals b.GroupID into res1
                                        from ab in res1.DefaultIfEmpty()
                                        join c in ctx.SiteInfos on ab.SiteID equals c.ID into res2
                                        from bc in res2.DefaultIfEmpty()
                                        where a.ID == tmpTarget.SiteGroup.ID
                                        orderby ab.Sort
                                        select new { A = a, AB = ab, BC = bc };
                        if (siteQuery != null && siteQuery.Count() > 0)
                        {
                            tmpTarget.SiteGroup.SiteInfoList = new List<SiteInfoGroupDTO>();
                            foreach (var siteItem in siteQuery)
                            {
                                if (item.AB != null && item.BC != null)
                                {
                                    SiteInfoGroupDTO groupBean = new SiteInfoGroupDTO();
                                    SiteInfo siteBean = new SiteInfo();
                                    EntityTools.CopyEntity(siteItem.BC, ref siteBean);
                                    EntityTools.CopyEntity(siteItem.AB, ref groupBean);
                                    groupBean.SiteInfo = siteBean;
                                    tmpTarget.SiteGroup.SiteInfoList.Add(groupBean);
                                }
                            }
                        }
                        resList.Add(tmpTarget);
                    }
                }
            }
            return resList;
        }

        /// <summary>
        /// 根据多个工单号查询扫码记录
        /// </summary>
        /// <param name="prods"></param>
        /// <returns></returns>
        public List<ProdProcScan> SearchScanByProds(List<string> prods)
        {
            List<ProdProcScan> resList = new List<ProdProcScan>();
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.ProdProcScans.Where(s => prods.Contains(s.ProdNumber));
                if (query != null && query.Count() > 0)
                {
                    resList = query.ToList();
                }
            }                
            return resList;
        }


        /// <summary>
        /// 通过工单单号查询扫码记录
        /// </summary>
        /// <param name="prodNo"></param>
        /// <returns></returns>
        public List<ProdProcScan> SearchScanForProdNumber(string prodNo)
        {
            List<ProdProcScan> resList = new List<ProdProcScan>();
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.ProdProcScans.Where(s => s.ProdNumber == prodNo).OrderBy(s => s.ScanDate);
                if (query != null && query.Count() > 0)
                {
                    resList.AddRange(query);
                }
            }
            return resList;
        }

        /// <summary>
        /// 根据条件查询扫码记录
        /// </summary>
        /// <param name="prodNo">工单号</param>
        /// <param name="siteID">站点ID</param>
        /// <returns></returns>
        public List<ProdProcScan> SearchScanForCondition(string prodNo, int siteID)
        {
            List<ProdProcScan> resList = new List<ProdProcScan>();
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.ProdProcScans.Where(s => s.ProdNumber == prodNo && s.SiteInfoID == siteID).OrderBy(s => s.ScanDate);
                if (query != null && query.Count() > 0)
                {
                    resList.AddRange(query);
                }
            }
            return resList;
        }


        /// <summary>
        /// 根据工单号查询工单状态的扫码记录
        /// </summary>
        /// <param name="prodNo"></param>
        /// <returns></returns>
        public List<ProdProcScan> SearchScanOnlyProdStatus(string prodNo)
        {
            List<ProdProcScan> resList = new List<ProdProcScan>();
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.ProdProcScans
                            join b in ctx.StatusInfos on a.StatusInfoID equals b.ID into res1
                            from ab in res1
                            join c in ctx.StatusTypes on ab.StypeID equals c.ID into res2
                            from bc in res2
                            where a.ProdNumber == prodNo && bc.StypeName == "工单状态"
                            orderby a.ScanDate
                            select new { A = a,AB = ab,BC = bc};
                if (query != null && query.Count() > 0)
                {
                    foreach (var item in query)
                    {
                        resList.Add(item.A);
                    }
                }
            }
            return resList;
        }


        /// <summary>
        /// 保存扫码记录
        /// </summary>
        /// <param name="target"></param>
        /// <param name="user"></param>
        /// <param name="site"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public int SaveProdProcessScan(TargetProdProcessDTO target, BaseUserModel user, SiteInfo site, StatusInfo status)
        {
            int count = 0;
            using (MesDB ctx = new MesDB())
            {
                SiteInfo tmpSite = this.GetEndSiteForSiteGroup(target.ProdNumber, site.SiteName);

                TargetProdProcess tmpTarget = new TargetProdProcess();
                EntityTools.CopyEntity(target,ref tmpTarget);

                string beforeStr = EntityTools.GetPropNameAndValue(tmpTarget);
                tmpTarget.ProdStatusID = status.ID;
                tmpTarget.CurrSiteID = site.ID;
                string afterStr = EntityTools.GetPropNameAndValue(tmpTarget);

                MesLog meslog = this.InitMesLog("target_prod_process", target.ID, beforeStr, afterStr, "update", user.user_name);
                ctx.MesLogs.Add(meslog);


                ProdProcScan scanBean = new ProdProcScan();
                scanBean.ProdProcID = target.ID;
                scanBean.ProdNumber = target.ProdNumber;
                scanBean.SiteInfoID = site.ID;
                scanBean.SiteName = site.SiteName;
                scanBean.StatusInfoID = status.ID;
                scanBean.StatusName = status.StatusValue;
                scanBean.ScanQty = target.ProdQty ?? 0;
                scanBean.ScanUser = user.user_name;
                scanBean.ScanDate = GetCurrDateTime();
                ctx.ProdProcScans.Add(scanBean);

                ctx.TargetProdProcesses.Attach(tmpTarget);
                ctx.Entry<TargetProdProcess>(tmpTarget).State = System.Data.Entity.EntityState.Modified;

                if (tmpSite != null && tmpSite.ID == site.ID)
                {
                    var query = ctx.TargetPPCycle.Where(t => t.ProdNumber == target.ProdNumber);
                    if (query != null && query.Count() > 0)
                    {
                        TargetPPCycle tmpBean = query.First();
                        switch (site.ParentID)
                        {
                            case 1:
                                tmpBean.SmtDate = scanBean.ScanDate;
                                break;
                            case 2:
                                tmpBean.WeldDate = scanBean.ScanDate;
                                break;
                            case 3:
                                tmpBean.TestDate = scanBean.ScanDate;
                                break;
                            case 4:
                                tmpBean.TestDate = scanBean.ScanDate;
                                break;
                            case 5:
                                tmpBean.PackDate = scanBean.ScanDate;
                                break;
                        }
                    }
                }

                count = ctx.SaveChanges();
            }
            return count;
        }


        /// <summary>
        /// 保存扫码记录，该方法用于包装结束站的扫码保存
        /// </summary>
        /// <param name="target">工单号</param>
        /// <param name="user">操作员工</param>
        /// <param name="site">当前站点</param>
        /// <param name="status">当前状态</param>
        /// <param name="scanQty">入库数量</param>
        /// <returns>该方法用于包装结束站点的扫码，该站点采用的扫码方式是分批扫码</returns>
        public int SaveProdProcessScan(TargetProdProcessDTO target, BaseUserModel user, SiteInfo site, StatusInfo status, decimal scanQty)
        {
            int count = 0;
            using (MesDB ctx = new MesDB())
            {
                //取得服务器的系统时间
                DateTime tmpDay = GetCurrDateTime();

                //根据要保存的站点，取得对应大站的结束站点
                SiteInfo tmpSite = this.GetEndSiteForSiteGroup(target.ProdNumber, site.SiteName);

                //取得工单该站点的已扫码数量 
                decimal clearQty = 0;
                var scanQuery = ctx.ProdProcScans.Where(s => s.ProdNumber == target.ProdNumber && s.SiteInfoID == site.ID);
                if (scanQuery != null && scanQuery.Count() > 0)
                {
                    clearQty = scanQuery.ToList<ProdProcScan>().Sum(s => s.ScanQty);
                }

                //如果工单  投产数量 <= 已经扫码数量 + 本次扫码数量，标记该工单完结
                Boolean isComp = target.ProdQty > clearQty + scanQty ? false : true;

                //如果该工单标记了完结，更新工单的当前站点、状态，并将本次的扫码时间当成工单的入库时间
                if (isComp == true)
                {
                    TargetProdProcess tmpTarget = new TargetProdProcess();
                    EntityTools.CopyEntity(target, ref tmpTarget);

                    string beforeStr = EntityTools.GetPropNameAndValue(tmpTarget);
                    tmpTarget.ProdStatusID = status.ID;
                    tmpTarget.CurrSiteID = site.ID;
                    string afterStr = EntityTools.GetPropNameAndValue(tmpTarget);

                    MesLog meslog = this.InitMesLog("target_prod_process", target.ID, beforeStr, afterStr, "update", user.user_name);
                    ctx.MesLogs.Add(meslog);

                    ctx.TargetProdProcesses.Attach(tmpTarget);
                    ctx.Entry<TargetProdProcess>(tmpTarget).State = System.Data.Entity.EntityState.Modified;

                    if (tmpSite != null && tmpSite.ID == site.ID)
                    {
                        var query = ctx.TargetPPCycle.Where(t => t.ProdNumber == target.ProdNumber);
                        if (query != null && query.Count() > 0)
                        {
                            TargetPPCycle tmpBean = query.First();
                            switch (site.ParentID)
                            {
                                case 1:
                                    tmpBean.SmtDate = tmpDay;
                                    break;
                                case 2:
                                    tmpBean.WeldDate = tmpDay;
                                    break;
                                case 3:
                                    tmpBean.TestDate = tmpDay;
                                    break;
                                case 4:
                                    tmpBean.TestDate = tmpDay;
                                    break;
                                case 5:
                                    tmpBean.PackDate = tmpDay;
                                    break;
                            }
                        }
                    }
                }

                //保存扫码记录
                ProdProcScan scanBean = new ProdProcScan();
                scanBean.ProdProcID = target.ID;
                scanBean.ProdNumber = target.ProdNumber;
                scanBean.SiteInfoID = site.ID;
                scanBean.SiteName = site.SiteName;
                scanBean.StatusInfoID = status.ID;
                scanBean.StatusName = status.StatusValue;
                scanBean.ScanQty = scanQty;
                scanBean.ScanUser = user.user_name;
                scanBean.ScanDate = GetCurrDateTime();
                scanBean.IsComp = isComp == true ? 1 : 0;
                ctx.ProdProcScans.Add(scanBean);

                count = ctx.SaveChanges();
            }
            return count;
        }

        /// <summary>
        /// 保存异常订单
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public int InsertExcepOrder(ExcepOrder order)
        {
            if (order != null)
            {
                using (MesDB ctx = new MesDB())
                {
                    ctx.ExcepOrder.Add(order);
                    int count = ctx.SaveChanges();
                    return count;
                }
            }
            else
            {
                throw new Exception("传入的异常订单资料为空！");
            }
        }


        /// <summary>
        /// 将工单的暂停状态取消
        /// </summary>
        /// <param name="targetList">工单</param>
        /// <param name="keeponStatus">取消暂停的状态码信息</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public int KeepOnProdProcess(List<TargetProdProcessDTO> targetList,StatusInfo keeponStatus)
        {
            if (targetList != null && targetList.Count > 0)
            {
                int count = 0;
                using (MesDB ctx = new MesDB())
                {
                    foreach (var item in targetList)
                    {
                        TargetProdProcess tmpTarget = new TargetProdProcess();
                        TargetProdProcess copyTarget = new TargetProdProcess();
                        EntityTools.CopyEntity<TargetProdProcessDTO, TargetProdProcess>(item, ref tmpTarget);
                        EntityTools.CopyEntity<TargetProdProcessDTO, TargetProdProcess>(item, ref copyTarget);

                        //取消暂停时，工单的异常状态设置暂停前的状态
                        tmpTarget.ErrStatusID = tmpTarget.TmpErrStatusID ?? 0;
                        tmpTarget.TmpErrStatusID = 0;
                        ctx.TargetProdProcesses.Attach(tmpTarget);
                        ctx.Entry(tmpTarget).State = System.Data.Entity.EntityState.Modified;

                        //取消暂停时，扫码记录中的状态为取消暂停状态
                        ProdProcScan tmpScan = new ProdProcScan();
                        tmpScan.ProdProcID = tmpTarget.ID;
                        tmpScan.ProdNumber = tmpTarget.ProdNumber;
                        tmpScan.SiteInfoID = tmpTarget.CurrSiteID;
                        tmpScan.SiteName = ctx.SiteInfos.Where(s => s.ID == tmpTarget.CurrSiteID).First().SiteName;
                        tmpScan.StatusInfoID = keeponStatus.ID;
                        tmpScan.StatusName = keeponStatus.StatusValue;
                        tmpScan.ScanQty = tmpTarget.ProdQty ?? 0;
                        tmpScan.ScanDate = DateTime.Now;
                        tmpScan.ScanUser = LoginFrm.LoginUser.user_name;
                        ctx.ProdProcScans.Add(tmpScan);

                        MesLog mesLog = new MesLog();
                        mesLog.TableName = "target_prod_process";
                        mesLog.TableID = tmpTarget.ID;
                        mesLog.BeforeData = EntityTools.GetPropNameAndValue(copyTarget);
                        mesLog.AfterData = EntityTools.GetPropNameAndValue(tmpTarget);
                        mesLog.ChangeType = "update";
                        mesLog.ChangeUser = LoginFrm.LoginUser.user_name;
                        mesLog.ChangeDate = DateTime.Now;
                        ctx.MesLogs.Add(mesLog);

                        count = ctx.SaveChanges();
                    }
                }
                return count;
            }
            else
            {
                throw new Exception("没有任何可以保存的资料！");
            }
        }


        /// <summary>
        /// 将工单暂停
        /// </summary>
        /// <param name="targetList">工单</param>
        /// <param name="pauseStatus">暂停的状态码信息</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public int PauseProdProcess(List<TargetProdProcessDTO> targetList,StatusInfo pauseStatus)
        {
            if (targetList != null && targetList.Count > 0)
            {
                int count = 0;
                using (MesDB ctx = new MesDB())
                {
                    foreach (var item in targetList)
                    {
                        TargetProdProcess tmpTarget = new TargetProdProcess();
                        TargetProdProcess copyTarget = new TargetProdProcess();
                        EntityTools.CopyEntity<TargetProdProcessDTO, TargetProdProcess>(item, ref tmpTarget);
                        EntityTools.CopyEntity<TargetProdProcessDTO, TargetProdProcess>(item, ref copyTarget);


                        tmpTarget.TmpErrStatusID = tmpTarget.ErrStatusID;
                        tmpTarget.ErrStatusID = pauseStatus.ID;
                        ctx.TargetProdProcesses.Attach(tmpTarget);
                        ctx.Entry(tmpTarget).State = System.Data.Entity.EntityState.Modified;

                        ProdProcScan tmpScan = new ProdProcScan();
                        tmpScan.ProdProcID = tmpTarget.ID;
                        tmpScan.ProdNumber = tmpTarget.ProdNumber;
                        tmpScan.SiteInfoID = tmpTarget.CurrSiteID;
                        tmpScan.SiteName = ctx.SiteInfos.Where(s => s.ID == tmpTarget.CurrSiteID).First().SiteName;
                        tmpScan.StatusInfoID = pauseStatus.ID;
                        tmpScan.StatusName = pauseStatus.StatusValue;
                        tmpScan.ScanQty = tmpTarget.ProdQty ?? 0;
                        tmpScan.ScanDate = DateTime.Now;
                        tmpScan.ScanUser = LoginFrm.LoginUser.user_name;
                        ctx.ProdProcScans.Add(tmpScan);

                        MesLog mesLog = new MesLog();
                        mesLog.TableName = "target_prod_process";
                        mesLog.TableID = tmpTarget.ID;
                        mesLog.BeforeData = EntityTools.GetPropNameAndValue(copyTarget);
                        mesLog.AfterData = EntityTools.GetPropNameAndValue(tmpTarget);
                        mesLog.ChangeType = "update";
                        mesLog.ChangeUser = LoginFrm.LoginUser.user_name;
                        mesLog.ChangeDate = DateTime.Now;
                        ctx.MesLogs.Add(mesLog);

                        count = ctx.SaveChanges();
                    }
                }
                return count;
            }
            else
            {
                throw new Exception("没有任何可以保存的资料！");
            }
        }


        /// <summary>
        /// 判断工单中某一站点所在的大站的结束站
        /// </summary>
        /// <param name="prod"></param>
        /// <param name="site"></param>
        /// <returns></returns>
        public SiteInfo GetEndSiteForSiteGroup(string prod, string site)
        {
            SiteInfo resBean = null;
            using (MesDB ctx = new MesDB())
            {
                SiteInfo tmpSite = null;
                var siteQuery = from a in ctx.SiteInfos 
                                join b in ctx.SiteInfos on a.ParentID equals b.ID into res
                                from ab in res
                                where a.SiteName == site
                                select ab;
                if (siteQuery != null && siteQuery.Count() > 0)
                {
                    tmpSite = siteQuery.First();
                }

                if (tmpSite != null)
                {
                    var query = from a in ctx.TargetProdProcesses
                                join b in ctx.ProdProcSites on a.ID equals b.ProdProcID into res1
                                from ab in res1
                                join c in ctx.SiteGroups on ab.SiteGroupID equals c.ID into res2
                                from bc in res2
                                join d in ctx.SiteInfoGroups on bc.ID equals d.GroupID into res3
                                from cd in res3
                                join e in ctx.SiteInfos on cd.SiteID equals e.ID into res4
                                from de in res4
                                where a.ProdNumber == prod
                                orderby cd.Sort descending
                                select new { A = a, CD = cd, DE = de };
                    if (query != null && query.Count() > 0)
                    {
                        foreach (var item in query)
                        {
                            if (item.DE.ParentID == tmpSite.ID)
                            {
                                resBean = item.DE;
                                break;
                            }
                        }
                    }
                }
                
                
            }
            return resBean;
        }


        /// <summary>
        /// 保存工单的扫码记录
        /// </summary>
        /// <param name="prod">工单</param>
        /// <param name="site">站点</param>
        /// <param name="status">状态</param>
        /// <param name="user">用户</param>
        /// <param name="ScanQty">扫码数量</param>
        /// <param name="isComp">是否已全部完成，1代表该工序扫码后已完结；0代表该工序本次扫码后仍未全部完成</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public int SaveProdProcessScan(TargetProdProcessDTO prod, SiteInfo site, StatusInfo status, BaseUserDTO user,decimal ScanQty,int isComp)
        {
            int count = 0;
            DateTime tmpDay = this.GetCurrDateTime();
            using (MesDB ctx = new MesDB())
            {
                //取得扫码站点所在的大站的终点站
                SiteInfo tmpSite = this.GetEndSiteForSiteGroup(prod.ProdNumber, site.SiteName);

                //更新工单的排单计划的完成状态
                var scheQuery = from a in ctx.ProdLineSettings
                                join b in ctx.ProdSchedules on a.ID equals b.LineID into res1
                                from ab in res1
                                join c in ctx.TargetProdProcesses on ab.ProdID equals c.ID into res2
                                from bc in res2
                                where (a.LastSiteID == site.ID || a.BeginSiteID == site.ID) && bc.ID == prod.ID
                                select new { A = a, AB = ab };
                if (scheQuery != null && scheQuery.Count() > 0)
                {
                    foreach (var item in scheQuery)
                    {
                        ProdSchedule scheBean = item.AB;
                        if (item.A.LastSiteID == site.ID && isComp == 1)
                        {
                            scheBean.IsComp = 1;
                            scheBean.CompDate = tmpDay;
                        }
                        else if (item.A.BeginSiteID == site.ID && scheBean.Remark != null && scheBean.Remark.Equals("未收到"))
                        {
                            scheBean.Remark = "";
                        }
                    }
                }


                TargetProdProcess tmpTarget = new TargetProdProcess();
                EntityTools.CopyEntity(prod, ref tmpTarget);

                //当扫码站点是包装开始时，根据扫码人员分配的生产线，决定工单所属的生产线
                var emplQuery = ctx.EmplInfos.AsQueryable();
                if (site.ID == 19)
                {
                    int compLineID = 0;
                    if (emplQuery != null)
                    {
                        var compEmplQuery = emplQuery.Where(q => q.EmplNumber == user.user_name);
                        var tmpList = new List<int>(new int[] { 6, 7, 8, 10, 11, 12, 15, 16 });
                        if (compEmplQuery != null && compEmplQuery.Count() > 0)
                        {
                            if (compEmplQuery.First().LineID == 5)
                            {
                                compLineID = compEmplQuery.First().LineID;
                            }
                            else if (tmpList.Contains(compEmplQuery.First().LineID))
                            {
                                compLineID = 16;
                            }
                        }
                    }

                    if (compLineID > 0)
                    {
                        tmpTarget.CompLineID = compLineID;
                    }
                    else
                    {
                        throw new Exception("未能确定扫码员工所属生产线，中止扫码！");
                    }
                }

                if (isComp == 1)
                {
                    tmpTarget.ProdStatusID = status.ID;
                    tmpTarget.CurrSiteID = site.ID;

                    //为工单的变更写日志文件
                    string beforeStr = EntityTools.GetPropNameAndValue(tmpTarget);
                    string afterStr = EntityTools.GetPropNameAndValue(tmpTarget);
                    MesLog meslog = this.InitMesLog("target_prod_process", prod.ID, beforeStr, afterStr, "update", user.user_name);
                    ctx.MesLogs.Add(meslog);

                    //更新工单信息
                    ctx.TargetProdProcesses.Attach(tmpTarget);
                    ctx.Entry<TargetProdProcess>(tmpTarget).State = System.Data.Entity.EntityState.Modified;

                    if (site.ID == 57)
                    {
                        string tmpSql = $"update CQProdNumberExcel set ISOK = 1 where prod_number = '{prod.ProdNumber}'";
                        ctx.Database.ExecuteSqlCommand(tmpSql);
                    }
                }

                

                ////保存扫码记录
                ProdProcScan scanBean = new ProdProcScan();
                scanBean.ProdProcID = prod.ID;
                scanBean.ProdNumber = prod.ProdNumber;
                scanBean.SiteInfoID = site.ID;
                scanBean.SiteName = site.SiteName;
                scanBean.StatusInfoID = status.ID;
                scanBean.StatusName = status.StatusValue;
                scanBean.ScanQty = ScanQty;
                scanBean.ScanUser = user.user_name;
                scanBean.ScanDate = GetCurrDateTime();
                scanBean.IsComp = isComp == 1 ? 1 : 0;
                ctx.ProdProcScans.Add(scanBean);

                

                //更新工单每个大站的完成时间
                if (isComp == 1 && tmpSite != null && tmpSite.ID == site.ID)
                {
                    var query = ctx.TargetPPCycle.Where(t => t.ProdNumber == prod.ProdNumber);
                    if (query != null && query.Count() > 0)
                    {
                        TargetPPCycle tmpBean = query.First();
                        switch (site.ParentID)
                        {
                            case 1:
                                tmpBean.SmtDate = scanBean.ScanDate;
                                break;
                            case 2:
                                tmpBean.WeldDate = scanBean.ScanDate;
                                break;
                            case 3:
                                tmpBean.TestDate = scanBean.ScanDate;
                                break;
                            case 4:
                                tmpBean.TestDate = scanBean.ScanDate;
                                break;
                            case 5:
                                tmpBean.PackDate = scanBean.ScanDate;
                                break;
                        }
                    }
                }

                count = ctx.SaveChanges();
            }
            return count;
        }
    }
}
